package com.lmy.quartz;

import org.quartz.*;

import java.util.Date;

/**
 * 定义一个定时任务类
 * Quartz框架默认在Scheduler每次执行，都会根据JobDetail创建一个新的Job实例。即忽略任务执行时间，严格按照间隔时间启动任务。
 * 1.当不想使用并发执行时，可以使用@DisallowConcurrentExecution注解 禁止并发执行，这样就会根据任务执行时间来依次启动任务
 * 2.由于每次执行任务时，job 和 jobDetail都是新的实例，所以对应JobDetail的jobDataMap也是新实例，那么存入的信息就会随着定时任务执行丢失
 *   可以使用@PersistJobDataAfterExecution注解来将jobDataMap“持久化”,即无论执行多少次，都会将之前任务的数据合并到下一次执行的jobDataMap中
 * 3.当一个任务不是持久化的，则当没有触发器Trigger关联它时，Quartz框架会从scheduler中删除它
 */
@DisallowConcurrentExecution
@PersistJobDataAfterExecution
public class MyJob implements Job {

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("====================================================");
        //Scheduler每次执行，都会根据JobDetail创建一个新的Job实例，可以规避并发访问问题
        System.out.println("jobDetail对象:" + System.identityHashCode(jobExecutionContext.getJobDetail()));
        System.out.println("job对象:" + System.identityHashCode(jobExecutionContext.getJobInstance()));
        //JobExecutionContext 是一个容器，可以获取定时任务相关的信息
        //1.获取JobDetail对象相关的信息 如 JobDataMap()
        JobDataMap jobDetailMap = jobExecutionContext.getJobDetail().getJobDataMap();
        System.out.println(jobDetailMap.getString("jobDetailInfo"));
        //执行次数+1
        int count = jobDetailMap.getInt("count");
        jobDetailMap.put("count", ++count);
        System.out.println("triggerMap count:" + jobDetailMap.getInt("count"));
        //2.获取Trigger对象相关的信息 如 JobDataMap()
        JobDataMap triggerMap = jobExecutionContext.getTrigger().getJobDataMap();
        System.out.println(triggerMap.getString("triggerInfo"));
        //3.获取JobDetail对象和Trigger对象相关的信息，就是将JobDetail和Trigger对象的jobDataMap合并
        JobDataMap mergedJobDataMap = jobExecutionContext.getMergedJobDataMap();
        System.out.println(mergedJobDataMap.getString("jobDetailInfo"));
        //4.当jobData中的某个key和定时任务对象的某个属性对应时，会自动调用setter方法设置属性
        System.out.println(this.name);  //jobDetail
        System.out.println("MyJob execute:" + new Date());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
